module MODULE_MULT #(
  WIDTH = 64,
	TOTAL_W = WIDTH + 2,
	PNUM = TOTAL_W/2
)(
	input								clk_i,
	input								rst_i,
	input								mul_valid_i,
	input		[1:0]				mul_signed_i, //low bit 1 mean multiplicand_i should be seem as signed
  input 	[WIDTH-1:0]	multiplicand_i,
  input 	[WIDTH-1:0]	multiplier_i,
  output 	[WIDTH-1:0] result_h_o,
  output 	[WIDTH-1:0]	result_l_o,
	output							result_valid_o
);
  wire	[TOTAL_W-1:0]   x  ;
  wire	[TOTAL_W-1:0]   y  ;
  wire  [2*TOTAL_W-1:0] result;

  assign x = {mul_signed_i[0] ? {2{multiplicand_i[WIDTH-1]}} : 2'b0, multiplicand_i[WIDTH-1:0]};
  assign y = {mul_signed_i[1] ? {2{multiplier_i[WIDTH-1]}} : 2'b0, multiplier_i[WIDTH-1:0]};

  // generate partial product:
  wire  [TOTAL_W:0] p[PNUM-1:0];
  wire  c [PNUM-1:0];

MODULE_booth #(.WIDTH (TOTAL_W)) B_0(.x (x),.s ({y[1:0], 1'b0}),.p (p[0]),.c (c[0]));
	genvar i;
	generate
  	for(i=1; i<PNUM; i++)begin
MODULE_booth #(.WIDTH (TOTAL_W)) B_(.x (x),.s (y[2*i+1 : 2*i-1]),.p (p[i]),.c (c[i]));
  	end
	endgenerate
  // use wallace tree to generate result:
  wire [2*TOTAL_W-1:0] tree_in [PNUM-1:0];
  assign tree_in[0] = {{(TOTAL_W-1){c[0]}} , p[0]	};
	generate
  	for(i=1; i<PNUM; i=i+1)begin
    	assign tree_in[i] = {{(TOTAL_W-1-2*i){p[i][TOTAL_W-1]}}, p[i], 1'b0, c[i-1], {(2*i-2){1'b0}}};
    	//assign tree_in[i] = {{(TOTAL_W-1-2*i){c[i]}}, p[i], 1'b0, c[i-1], {(2*i-2){1'b0}}};
  	end
	endgenerate

MODULE_wallace_tree #(2*TOTAL_W) my_wallace_tree (
		.clk_i					(clk_i),
		.rst_i					(rst_i),
		.valid_i				(mul_valid_i),
		.in							(tree_in),
		.result_o				(result),
		.result_valid_o	(result_valid_o)
	);

  assign {result_h_o[WIDTH-1:0], result_l_o[WIDTH-1:0]} = result[2*WIDTH-1:0];

endmodule
